﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using alib.Debugging;

namespace agree
{
	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <summary>
	/// 
	/// </summary>
	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	public struct FeatMark : IEquatable<FeatMark>, IComparable<FeatMark>
	{
		public static FeatMark RootNode = new FeatMark(-1, 0);
		public static FeatMark Invalid = new FeatMark(int.MaxValue, 0);

		[DebuggerStepThrough]
		public FeatMark(int i_feat, int m)
		{
			this.i_feat = i_feat;
			this.m = m;
		}
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		public int i_feat;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		public int m;

		public bool Equals(FeatMark other)
		{
			return m == other.m && i_feat == other.i_feat;
		}
		public override int GetHashCode()
		{
			return (m << 16) | (ushort)i_feat;
		}
		public int CompareTo(FeatMark other)
		{
			int d = m - other.m;
			return d != 0 ? d : i_feat - other.i_feat;
		}
		public String ShortDisplay(FeatMgr ftm)
		{
			if (ftm == null)
				return "(n/a)";
			return String.Format("{0}/{1}", m, ftm[i_feat].FEATURE);
		}
	};

	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <summary>
	/// 
	/// </summary>
	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	public struct TmFeatMark : IEquatable<TmFeatMark>
	{
		public TmFeatMark(FeatMgr rtc, FeatMark fm)
		{
			this.ftm = rtc;
			this.fm = fm;
		}
		public TmFeatMark(FeatMgr fcm, int i_feat, int m)
			: this(fcm, new FeatMark(i_feat, m))
		{
		}

		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		public FeatMgr ftm;
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		public FeatMark fm;

		public int i_feat { get { return fm.i_feat; } }

		public int m { get { return fm.m; } }

		public bool Equals(TmFeatMark other)
		{
			return fm.Equals(other.fm) && ftm == other.ftm;
		}
		public override int GetHashCode()
		{
			return fm.GetHashCode() ^ ftm.GetHashCode();
		}
		public override bool Equals(object obj)
		{
			return obj is TmFeatMark && Equals((TmFeatMark)obj);
		}
		public Edge Constraint(Tfs tfs)
		{
			Edge e;
			tfs.TryGetEdge(fm.i_feat, fm.m, out e);
			return e;
		}
		public void SetConstraint(WriteableTfs tfs, Edge e)
		{
			tfs.SetEdge(fm.i_feat, fm.m, e);
		}
	};
}
